package com.ziiwee.reduce.describe.types.impls;

import com.ziiwee.reduce.describe.FieldDescribe;
import com.ziiwee.reduce.describe.TypeDescribe;
import com.ziiwee.reduce.describe.annotations.Label;
import com.ziiwee.reduce.describe.models.FieldDescribeModel;
import com.ziiwee.reduce.describe.models.TypeDescribeModel;
import com.ziiwee.reduce.describe.types.TypeProvider;
import com.ziiwee.reduce.describe.types.TypeProviderContext;
import lombok.Data;
import org.springframework.core.ResolvableType;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Objects;

/**
 * @author ziiwee
 * @date 2020/8/13
 */
public class PageTypeProvider implements TypeProvider {
    @Override
    public boolean support(ResolvableType type) {
        return Page.class.equals(type.resolve()) || PageImpl.class.equals(type.resolve());
    }

    @Override
    public TypeDescribe render(ResolvableType type, TypeProviderContext context) {
//        TypeDescribe page = context.render(type);
        TypeDescribe pageModel = context.renderNew(ResolvableType.forClass(PageModel.class));
//        TypeMeta pageModel = context.render(ResolvableType.forClass(PageModel.class));
        for (FieldDescribe field : pageModel.getFields()) {
            if (Objects.equals(field.getName(), "content")) {
                ResolvableType contentType = ResolvableType.forClassWithGenerics(List.class, type.getGeneric(0).getRawClass());
                FieldDescribeModel model = (FieldDescribeModel) field;
                model.setType(contentType);
//                model.setType(ReflectUtil.getSimpleNameByResolvableType(contentType));
            }
            context.render(field.getType());
        }
        TypeDescribeModel model = (TypeDescribeModel) pageModel;
        model.setName(pageModel.getName());
        model.setType(pageModel.getType());
//        context.putCache(model.getType().toString(), model);
        return model;
    }

    @Label("分页")
    @Data
    public static class PageModel {
        @Label("内容")
        @NotNull
        private List<Object> content;
        @Label("每页条数")
        @NotNull
        private Integer size;
        @Label("当前页数")
        @NotNull
        private Integer number;
        @Label("总页数")
        @NotNull
        private Integer totalPages;
        @Label("总条数")
        @NotNull
        private Integer totalElements;
        private Integer numberOfElements;
        @Label("首页")
        @NotNull
        private Boolean first;
        @Label("末页")
        @NotNull
        private Boolean last;
        @Label("是否为空列表")
        @NotNull
        private Boolean empty;
        @Label("分页信息")
        @NotNull
        private Pageable pageable;
    }
}
